[IA64] convert stats to perfc, get rid of unsafe hypercall
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 14 Aug 2006 19:20:40 +0000 (13:20 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 14 Aug 2006 19:20:40 +0000 (13:20 -0600)
Convert remaining stat counter to perfc.
Get rid of unsafe hypercall.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
12 files changed:
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/faults.c
xen/arch/ia64/xen/hypercall.c
xen/arch/ia64/xen/privop.c
xen/arch/ia64/xen/privop_stat.c
xen/arch/ia64/xen/vcpu.c
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/config.h
xen/include/asm-ia64/perfc.h
xen/include/asm-ia64/perfc_defn.h
xen/include/asm-ia64/privop_stat.h
xen/include/asm-ia64/vhpt.h

index 86ff7d85f54ec90cbab06edfa22a82130a0f8f38..5258c40f95bb32d605c1ff13914afef9befc2895 100644 (file)
@@ -47,7 +47,6 @@
 #include <asm/regionreg.h>
 #include <asm/dom_fw.h>
 #include <asm/shadow.h>
-#include <asm/privop_stat.h>
 
 unsigned long dom0_size = 512*1024*1024;
 unsigned long dom0_align = 64*1024*1024;
index a37dfc8c80b632a7fb8a85b03f5ed6bf717a114b..16bef26b31d840d57d4e9c41588c7d7452825746 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/debugger.h>
 #include <asm/fpswa.h>
 #include <asm/bundle.h>
-#include <asm/privop_stat.h>
 #include <asm/asm-xsi-offsets.h>
 #include <asm/shadow.h>
 
index 97924b8776b7b6c163e25856b070baeaa543b0f5..6fcc1ef72e625d840d704c3248bd1715a7cf7d94 100644 (file)
@@ -28,7 +28,6 @@
 #include <xen/domain.h>
 #include <public/callback.h>
 #include <xen/event.h>
-#include <asm/privop_stat.h>
 
 static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
 static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
@@ -275,11 +274,6 @@ fw_hypercall (struct pt_regs *regs)
        return IA64_NO_FAULT;
 }
 
-/* opt_unsafe_hypercall: If true, unsafe debugging hypercalls are allowed.
-   These can create security hole.  */
-static int opt_unsafe_hypercall = 0;
-boolean_param("unsafe_hypercall", opt_unsafe_hypercall);
-
 IA64FAULT
 ia64_hypercall (struct pt_regs *regs)
 {
@@ -287,32 +281,6 @@ ia64_hypercall (struct pt_regs *regs)
        unsigned long index = regs->r2;
        int privlvl = (regs->cr_ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
 
-       if (index >= FW_HYPERCALL_FIRST_USER) {
-           /* Note: user hypercalls are not safe, since Xen doesn't
-              check memory access privilege: Xen does not deny reading
-              or writing to kernel memory.  */
-           if (!opt_unsafe_hypercall) {
-               printf("user xen/ia64 hypercalls disabled\n");
-               regs->r8 = -1;
-           }
-           else switch (index) {
-               case 0xffff:
-                       regs->r8 = dump_privop_counts_to_user(
-                               (char *) vcpu_get_gr(v,32),
-                               (int) vcpu_get_gr(v,33));
-                       break;
-               case 0xfffe:
-                       regs->r8 = zero_privop_counts_to_user(
-                               (char *) vcpu_get_gr(v,32),
-                               (int) vcpu_get_gr(v,33));
-                       break;
-               default:
-                       printf("unknown user xen/ia64 hypercall %lx\n", index);
-                       regs->r8 = do_ni_hypercall();
-           }
-           return IA64_NO_FAULT;
-       }
-
        /* Hypercalls are only allowed by kernel.
           Kernel checks memory accesses.  */
        if (VMX_DOMAIN(v) ? (privlvl != 0) : (privlvl != 2)) {
index 0172dd87c33d19a395c2fd4dd183af9586bf7977..2053317e51240a8bb513548ae9917e049cabb50b 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/dom_fw.h>
 #include <asm/vhpt.h>
 #include <asm/bundle.h>
-#include <asm/privop_stat.h>
 
 long priv_verbose=0;
 unsigned long privop_trace = 0;
index 466b5b1ffdb64552e75119daafd31710521d3ec2..5bdd5adc6a832fc8bfa5540a53b7c0adfafa9d1b 100644 (file)
@@ -1,26 +1,55 @@
-#include <asm/privop_stat.h>
-#include <asm/vhpt.h>
 #include <xen/lib.h>
-#include <asm/uaccess.h>
+#include <public/xen.h>
+#include <xen/perfc.h>
+#include <asm/atomic.h>
+#include <asm/privop_stat.h>
 
-#ifdef PRIVOP_ADDR_COUNT
-#define PRIVOP_COUNT_NINSTS 2
-#define PRIVOP_COUNT_NADDRS 30
+#ifdef CONFIG_PRIVOP_ADDRS
 
 struct privop_addr_count {
-       const char *instname;
        unsigned long addr[PRIVOP_COUNT_NADDRS];
-       unsigned long count[PRIVOP_COUNT_NADDRS];
-       unsigned long overflow;
+       unsigned int count[PRIVOP_COUNT_NADDRS];
+       unsigned int overflow;
+       atomic_t *perfc_addr;
+       atomic_t *perfc_count;
+       atomic_t *perfc_overflow;
 };
 
+#undef  PERFCOUNTER
+#define PERFCOUNTER(var, name)
+
+#undef  PERFCOUNTER_CPU
+#define PERFCOUNTER_CPU(var, name)
+
+#undef  PERFCOUNTER_ARRAY
+#define PERFCOUNTER_ARRAY(var, name, size)
+
+#undef  PERFSTATUS
+#define PERFSTATUS(var, name)
+
+#undef  PERFSTATUS_CPU
+#define PERFSTATUS_CPU(var, name)
+
+#undef  PERFSTATUS_ARRAY
+#define PERFSTATUS_ARRAY(var, name, size)
 
-static struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = {
-       [_GET_IFA] = { "=ifa",  { 0 }, { 0 }, 0 },
-       [_THASH] = { "thash", { 0 }, { 0 }, 0 }
+#undef PERFPRIVOPADDR
+#define PERFPRIVOPADDR(name)                        \
+    {                                               \
+        { 0 }, { 0 }, 0,                            \
+        perfcounters.privop_addr_##name##_addr,     \
+        perfcounters.privop_addr_##name##_count,    \
+        perfcounters.privop_addr_##name##_overflow  \
+    },
+
+static struct privop_addr_count privop_addr_counter[] = {
+#include <asm/perfc_defn.h>
 };
 
-void privop_count_addr(unsigned long iip, int inst)
+#define PRIVOP_COUNT_NINSTS \
+        (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
+
+void privop_count_addr(unsigned long iip, enum privop_inst inst)
 {
        struct privop_addr_count *v = &privop_addr_counter[inst];
        int i;
@@ -41,29 +70,28 @@ void privop_count_addr(unsigned long iip, int inst)
        v->overflow++;;
 }
 
-static int dump_privop_addrs(char *buf)
+void gather_privop_addrs(void)
 {
        int i, j;
-       char *s = buf;
-       s += sprintf(s, "Privop addresses:\n");
+       atomic_t *v;
        for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
-               struct privop_addr_count *v = &privop_addr_counter[i];
-               s += sprintf(s, "%s:\n", v->instname);
-               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) {
-                       if (!v->addr[j])
-                               break;
-                       s += sprintf(s, " at 0x%lx #%ld\n",
-                                    v->addr[j], v->count[j]);
-               }
-               if (v->overflow) 
-                       s += sprintf(s, " other #%ld\n", v->overflow);
+               /* Note: addresses are truncated!  */
+               v = privop_addr_counter[i].perfc_addr;
+               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                       atomic_set(&v[j], privop_addr_counter[i].addr[j]);
+
+               v = privop_addr_counter[i].perfc_count;
+               for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+                       atomic_set(&v[j], privop_addr_counter[i].count[j]);
+               
+               atomic_set(privop_addr_counter[i].perfc_overflow,
+                          privop_addr_counter[i].overflow);
        }
-       return s - buf;
 }
 
-static void zero_privop_addrs(void)
+void reset_privop_addrs(void)
 {
-       int i,j;
+       int i, j;
        for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
                struct privop_addr_count *v = &privop_addr_counter[i];
                for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
@@ -119,30 +147,3 @@ static const char * const hyperpriv_str[HYPERPRIVOP_MAX+1] = {
        "=rr", "rr=", "kr=", "fc", "=cpuid", "=pmd", "=ar.eflg", "ar.eflg="
 };
 #endif
-
-#define TMPBUFLEN 8*1024
-int dump_privop_counts_to_user(char __user *ubuf, int len)
-{
-       char buf[TMPBUFLEN];
-       int n;
-
-       if (len < TMPBUFLEN)
-               return -1;
-
-       n = 0;
-#ifdef PRIVOP_ADDR_COUNT
-       n += dump_privop_addrs(buf + n);
-#endif
-       n += dump_vhpt_stats(buf + n);
-       if (__copy_to_user(ubuf,buf,n))
-               return -1;
-       return n;
-}
-
-int zero_privop_counts_to_user(char __user *ubuf, int len)
-{
-#ifdef PRIVOP_ADDR_COUNT
-       zero_privop_addrs();
-#endif
-       return 0;
-}
index 18fd1989b8d062ee36989d13e9691075c7445a7d..acbc492686db47fa2425e7e0ddae5be57cf403f1 100644 (file)
@@ -473,7 +473,7 @@ IA64FAULT vcpu_get_iip(VCPU *vcpu, UINT64 *pval)
 
 IA64FAULT vcpu_get_ifa(VCPU *vcpu, UINT64 *pval)
 {
-       PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_GET_IFA);
+       PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_get_ifa);
        *pval = PSCB(vcpu,ifa);
        return (IA64_NO_FAULT);
 }
@@ -540,7 +540,7 @@ IA64FAULT vcpu_get_iim(VCPU *vcpu, UINT64 *pval)
 
 IA64FAULT vcpu_get_iha(VCPU *vcpu, UINT64 *pval)
 {
-       PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_THASH);
+       PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_thash);
        *pval = PSCB(vcpu,iha);
        return (IA64_NO_FAULT);
 }
index 9789c0010a54e578c85997481f1f40fa3ea9c721..7df751c2c724d9856cec65e611ed39622c0b2567 100644 (file)
@@ -261,13 +261,12 @@ void flush_tlb_mask(cpumask_t mask)
             (cpu, (void (*)(void *))flush_tlb_vhpt_all, NULL, 1, 1);
 }
 
-int dump_vhpt_stats(char *buf)
+#ifdef PERF_COUNTERS
+void gather_vhpt_stats(void)
 {
        int i, cpu;
-       char *s = buf;
 
-       s += sprintf(s,"VHPT usage (%ld entries):\n",
-                    (unsigned long) VHPT_NUM_ENTRIES);
+       perfc_set(vhpt_nbr_entries, VHPT_NUM_ENTRIES);
 
        for_each_present_cpu (cpu) {
                struct vhpt_lf_entry *v = __va(per_cpu(vhpt_paddr, cpu));
@@ -276,8 +275,7 @@ int dump_vhpt_stats(char *buf)
                for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
                        if (!(v->ti_tag & INVALID_TI_TAG))
                                vhpt_valid++;
-               s += sprintf(s,"  cpu %d: %ld\n", cpu, vhpt_valid);
+               perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
        }
-
-       return s - buf;
 }
+#endif
index 12d48f7baf88e212845d4124a2109bb7f75a9d90..e1a49620749f2beb5290c471332007192ada35c4 100644 (file)
 
 #define MAX_DMADOM_PFN (0x7FFFFFFFUL >> PAGE_SHIFT) /* 31 addressable bits */
 
+/* If PERFC is used, include privop maps.  */
+#ifdef PERF_COUNTERS
+#define CONFIG_PRIVOP_ADDRS
+#define PRIVOP_COUNT_NADDRS 30
+#endif
+
 #ifndef __ASSEMBLY__
 
 // can't find where this typedef was before?!?
index 37a0ac3bc540b1ef99d88f89a1eeb943c3b3b038..0ca2189622794c5b503ac0c0df50cd09e662f294 100644 (file)
@@ -1,16 +1,22 @@
 #ifndef __ASM_PERFC_H__
 #define __ASM_PERFC_H__
 
-static inline void arch_perfc_printall (void)
+#include <asm/vhpt.h>
+#include <asm/privop_stat.h>
+
+static inline void arch_perfc_printall(void)
 {
 }
 
-static inline void arch_perfc_reset (void)
+static inline void arch_perfc_reset(void)
 {
+  reset_privop_addrs();
 }
 
-static inline void arch_perfc_gather (void)
+static inline void arch_perfc_gather(void)
 {
+  gather_vhpt_stats();
+  gather_privop_addrs();
 }
 
 #endif
index f09e90d03aa9c8f148b0c4a27ee5710fc1e91fd5..d3776611ffdea8fa9b39e433920999d23f89fce4 100644 (file)
@@ -40,3 +40,20 @@ PERFCOUNTER_ARRAY(fast_hyperprivop,   "fast hyperprivops", HYPERPRIVOP_MAX + 1)
 
 PERFCOUNTER_ARRAY(slow_reflect,       "slow reflection", 0x80)
 PERFCOUNTER_ARRAY(fast_reflect,       "fast reflection", 0x80)
+
+PERFSTATUS(vhpt_nbr_entries,          "nbr of entries per VHPT")
+PERFSTATUS_CPU(vhpt_valid_entries,    "nbr of valid entries in VHPT")
+
+#ifdef CONFIG_PRIVOP_ADDRS
+#ifndef PERFPRIVOPADDR
+#define PERFPRIVOPADDR(name) \
+PERFSTATUS_ARRAY(privop_addr_##name##_addr, "privop-addrs addr " #name, \
+                 PRIVOP_COUNT_NADDRS) \
+PERFSTATUS_ARRAY(privop_addr_##name##_count, "privop-addrs count " #name, \
+                 PRIVOP_COUNT_NADDRS) \
+PERFSTATUS(privop_addr_##name##_overflow, "privop-addrs overflow " #name)
+#endif
+
+PERFPRIVOPADDR(get_ifa)
+PERFPRIVOPADDR(thash)
+#endif
index b48a39ed3ced2d085d85278d4c7c1a2571d4328c..a5ea27ad82b2373fd55239044a91a58edb524dec 100644 (file)
@@ -1,22 +1,46 @@
 #ifndef _XEN_UA64_PRIVOP_STAT_H
 #define _XEN_UA64_PRIVOP_STAT_H
-#include <public/arch-ia64.h>
+#include <asm/config.h>
 
-extern int dump_privop_counts_to_user(char *, int);
-extern int zero_privop_counts_to_user(char *, int);
+#ifdef CONFIG_PRIVOP_ADDRS
 
-#define PRIVOP_ADDR_COUNT
+extern void gather_privop_addrs(void);
+extern void reset_privop_addrs(void);
 
-#ifdef PRIVOP_ADDR_COUNT
+#undef  PERFCOUNTER
+#define PERFCOUNTER(var, name)
+
+#undef  PERFCOUNTER_CPU
+#define PERFCOUNTER_CPU(var, name)
+
+#undef  PERFCOUNTER_ARRAY
+#define PERFCOUNTER_ARRAY(var, name, size)
+
+#undef  PERFSTATUS
+#define PERFSTATUS(var, name)
+
+#undef  PERFSTATUS_CPU
+#define PERFSTATUS_CPU(var, name)
+
+#undef  PERFSTATUS_ARRAY
+#define PERFSTATUS_ARRAY(var, name, size)
+
+#undef  PERFPRIVOPADDR
+#define PERFPRIVOPADDR(name) privop_inst_##name,
+
+enum privop_inst {
+#include <asm/perfc_defn.h>
+};
+
+#undef PERFPRIVOPADDR
 
-/* INST argument of PRIVOP_COUNT_ADDR.  */
-#define _GET_IFA 0
-#define _THASH 1
 #define        PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst)
-extern void privop_count_addr(unsigned long addr, int inst);
+extern void privop_count_addr(unsigned long addr, enum privop_inst inst);
 
 #else
-#define        PRIVOP_COUNT_ADDR(x,y) do {} while (0)
+#define PRIVOP_COUNT_ADDR(x,y) do {} while (0)
+#define gather_privop_addrs() do {} while (0)
+#define reset_privop_addrs() do {} while (0)
 #endif
 
 #endif /* _XEN_UA64_PRIVOP_STAT_H */
index afd3d7f2794ab755a1a468d9d3e12462c4abe970..cb4fc30462f209b8f5d2ab138b76fc4fd37dcdf7 100644 (file)
@@ -32,7 +32,7 @@ struct vhpt_lf_entry {
 #define INVALID_TI_TAG 0x8000000000000000L
 
 extern void vhpt_init (void);
-extern int dump_vhpt_stats(char *buf);
+extern void gather_vhpt_stats(void);
 extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
                                 unsigned long logps);
 extern void vhpt_insert (unsigned long vadr, unsigned long pte,